﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Routing;

namespace StockMatch.WebSite.Mvc
{
    public static class UrlHelperExtensions
    {
        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName)
        {
            return DomainRouteUrl(helper, routeName, new RouteValueDictionary());
        }

        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <param name="action">action名称</param>
        /// <param name="controller">controller名称</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName, string action, string controller)
        {
            return DomainRouteUrl(helper, routeName, new { controller = controller, action = action });
        }


        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <param name="routeValues">一个包含路由参数的对象</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName, object routeValues)
        {
            return DomainRouteUrl(helper, routeName, new RouteValueDictionary(routeValues));
        }

        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <param name="routeValues">一个包含路由参数的对象</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName, object routeValues, HtmlHelper htmlHelper)
        {
            var routeValueDictionary = new RouteValueDictionary(routeValues);
            var keys = htmlHelper.ViewContext.HttpContext.Request.QueryString;
            foreach (string key in keys.Keys)
            {
                if (!routeValueDictionary.ContainsKey(key))
                {
                    routeValueDictionary.Add(key, keys[key]);
                }
            }
            return DomainRouteUrl(helper, routeName, routeValueDictionary);
        }




        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <param name="routeValues">一个包含路由参数的对象</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName, RouteValueDictionary routeValues)
        {
            return DomainRouteUrl(helper, routeName, routeValues, "http");

        }

        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <param name="routeValues"></param>
        /// <param name="protocol">URL 协议，如“http”或“https”。</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName, object routeValues, string protocol)
        {
            return DomainRouteUrl(helper, routeName, new RouteValueDictionary(routeValues), protocol);
        }

        /// <summary>
        /// 使用路由名称为指定的路由值生成完全限定 URL，（支持子域DomainRoute）
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="routeName">用于生成 URL 的路由的名称。</param>
        /// <param name="routeValues"></param>
        /// <param name="protocol">URL 协议，如“http”或“https”。</param>
        /// <returns>完全限定 URL</returns>
        public static string DomainRouteUrl(this UrlHelper helper, string routeName, RouteValueDictionary routeValues, string protocol)
        {
            return DomainRouteUrl(helper, routeName, routeValues, protocol, string.Empty);
        }

        public static string DomainRouteUrl(this UrlHelper helper, string routeName, object routeValues, string protocol, string hostName)
        {
            return DomainRouteUrl(helper, routeName, new RouteValueDictionary(routeValues), protocol, hostName);
        }


        public static string DomainRouteUrl(this UrlHelper helper, string routeName, RouteValueDictionary routeValues, string protocol, string hostName)
        {
            if (string.IsNullOrWhiteSpace(routeName))
            {
                throw new Exception("参数routeName不能为空");
            }
            var route = RouteTable.Routes[routeName];

            if (route == null)
            {
                throw new Exception(string.Format("未找到名为{0}的route", routeName));
            }

            if (route is DomainRoute && !((DomainRoute)RouteTable.Routes[routeName]).Domain.Equals(helper.RequestContext.HttpContext.Request.Url.Host, StringComparison.OrdinalIgnoreCase))
            {
                return helper.RouteUrl(routeName, routeValues, protocol, ((DomainRoute)RouteTable.Routes[routeName]).Domain);
            }

            if (string.IsNullOrEmpty(protocol) && string.IsNullOrEmpty(hostName))
            {
                return helper.RouteUrl(routeName, routeValues);
            }
            else
            {
                if (string.IsNullOrEmpty(protocol))
                {
                    protocol = "http";
                }
                if (string.IsNullOrEmpty(hostName))
                {
                    hostName = helper.RequestContext.HttpContext.Request.Url.Host;
                }
                return helper.RouteUrl(routeName, routeValues, protocol, hostName);
            }
        }
    }
}
